package com.xianyun.rpc.server.impl;

import com.xianyun.rpc.RpcApplication;
import com.xianyun.rpc.constant.SerializerKeys;
import com.xianyun.rpc.model.RpcRequest;
import com.xianyun.rpc.model.RpcResponse;
import com.xianyun.rpc.registry.LocalRegistry;
import com.xianyun.rpc.serializer.Serializer;
import com.xianyun.rpc.serializer.SerializerFactory;
import com.xianyun.rpc.serializer.impl.JdkSerializer;
import com.xianyun.rpc.serializer.impl.JsonSerializer;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * Http 服务处理 为服务提供者提供服务
 *
 * @author xianYun
 * @version 1.0
 **/
public class HttpServerHandler implements Handler<HttpServerRequest> {
    @Override
    public void handle(HttpServerRequest request) {

        //指定序列化器
        //final Serializer serializer = new JsonSerializer();
        final Serializer serializer = SerializerFactory.getSerializer(RpcApplication.getRpcConfig().getSerializer());
        //记录日志
        System.out.println("Received request: " + request.method() + " " + request.uri());
        //异步处理 Http 请求
        request.bodyHandler(body -> {
            byte[] bytes = body.getBytes();
            RpcRequest rpcRequest = null;
            try {
                rpcRequest = serializer.deserialize(bytes, RpcRequest.class);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            //构建响应结果对象（当请求为空的时候）
            RpcResponse rpcResponse = new RpcResponse();
            if (rpcRequest == null) {
                rpcResponse.setMessage("rpcRequest is null");
                doResponse(request, rpcResponse, serializer);
                return;
            }

            //当请求不为空的时候的处理逻辑
            try {
               //获取服务对应实现类
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                //获取服务对应实现类方法
                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                //调用服务实现类方法
                Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
                //封装返回结果
                rpcResponse.setData(result);
                rpcResponse.setDataType(method.getReturnType());
                rpcResponse.setMessage("success");
            } catch (Exception e) {
                //出现异常时构建请求
                e.printStackTrace();
                rpcResponse.setMessage(e.getMessage());
                rpcResponse.setException(e);
            }
            // 响应
            doResponse(request, rpcResponse, serializer);
        });
    }

    /**
     * 响应
     *
     * @param request
     * @param rpcResponse
     * @param serializer
     */
    void doResponse(HttpServerRequest request, RpcResponse rpcResponse, Serializer serializer) {
        HttpServerResponse httpServerResponse = request.response()
                .putHeader("content-type", "application/json");
        try {
            // 序列化
            byte[] serialized = serializer.serialize(rpcResponse);
            httpServerResponse.end(Buffer.buffer(serialized));
        } catch (IOException e) {
            e.printStackTrace();
            httpServerResponse.end(Buffer.buffer());
        }
    }
}
